package com.uniflow.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uniflow.common.PageResult;
import com.uniflow.common.Result;
import com.uniflow.common.ResultCode;
import com.uniflow.entity.ApiApplication;
import com.uniflow.service.ApiApplicationService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * API应用管理控制器
 * 
 * @author uniflow
 * @since 1.0.0
 */
@RestController
@RequestMapping("/api/v1/api-applications")
@Validated
@Api(tags = "API应用管理")
public class ApiApplicationController {
    
    @Autowired
    private ApiApplicationService apiApplicationService;
    
    /**
     * 分页查询API应用列表
     */
    @GetMapping
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("分页查询API应用列表")
    public Result<PageResult<ApiApplication>> getApplicationList(
            @ApiParam("页码") @RequestParam(defaultValue = "1") int pageNum,
            @ApiParam("页大小") @RequestParam(defaultValue = "10") int pageSize,
            @ApiParam("应用名称") @RequestParam(required = false) String appName,
            @ApiParam("状态") @RequestParam(required = false) Integer status,
            @ApiParam("联系邮箱") @RequestParam(required = false) String contactEmail,
            @ApiParam("关键词") @RequestParam(required = false) String keyword) {
        try {
            IPage<ApiApplication> page = apiApplicationService.getApplicationPage(pageNum, pageSize, appName, status, contactEmail, keyword);
            PageResult<ApiApplication> result = new PageResult<ApiApplication>(pageNum, pageSize, page.getTotal(), page.getRecords());
            return Result.success(result);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据ID查询应用详情
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("根据ID查询应用详情")
    public Result<ApiApplication> getApplicationById(@ApiParam("应用ID") @PathVariable String id) {
        try {
            ApiApplication application = apiApplicationService.getApplicationWithKeys(id);
            if (application == null) {
                return Result.error(ResultCode.NOT_FOUND, "API应用不存在");
            }
            return Result.success(application);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 根据应用名称查询
     */
    @GetMapping("/name/{appName}")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("根据应用名称查询")
    public Result<ApiApplication> getApplicationByName(@ApiParam("应用名称") @PathVariable String appName) {
        try {
            ApiApplication application = apiApplicationService.getApplicationByName(appName);
            if (application == null) {
                return Result.error(ResultCode.NOT_FOUND, "API应用不存在");
            }
            return Result.success(application);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询启用的应用列表
     */
    @GetMapping("/enabled")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询启用的应用列表")
    public Result<List<ApiApplication>> getEnabledApplications() {
        try {
            List<ApiApplication> applications = apiApplicationService.getEnabledApplications();
            return Result.success(applications);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用统计信息
     */
    @GetMapping("/{id}/stats")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用统计信息")
    public Result<ApiApplication.ApiApplicationStats> getApplicationStats(@ApiParam("应用ID") @PathVariable String id) {
        try {
            ApiApplication.ApiApplicationStats stats = apiApplicationService.getApplicationStats(id);
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 创建API应用
     */
    @PostMapping
    @PreAuthorize("hasAuthority('api_app:write')")
    @ApiOperation("创建API应用")
    public Result<ApiApplication> createApplication(@Valid @RequestBody CreateApplicationRequest request) {
        try {
            ApiApplication application = new ApiApplication();
            application.setAppName(request.getAppName());
            application.setDescription(request.getDescription());
            application.setContactEmail(request.getContactEmail());
            application.setAllowedIps(request.getAllowedIps());
            application.setStatus(request.getStatus());
            
            ApiApplication createdApplication = apiApplicationService.createApplication(application);
            return Result.success(createdApplication);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 更新API应用
     */
    @PutMapping("/{id}")
    @PreAuthorize("hasAuthority('api_app:write')")
    @ApiOperation("更新API应用")
    public Result<ApiApplication> updateApplication(
            @ApiParam("应用ID") @PathVariable String id,
            @Valid @RequestBody UpdateApplicationRequest request) {
        try {
            ApiApplication application = new ApiApplication();
            application.setId(id);
            application.setAppName(request.getAppName());
            application.setDescription(request.getDescription());
            application.setContactEmail(request.getContactEmail());
            application.setAllowedIps(request.getAllowedIps());
            application.setStatus(request.getStatus());
            
            ApiApplication updatedApplication = apiApplicationService.updateApplication(application);
            return Result.success(updatedApplication);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 删除API应用
     */
    @DeleteMapping("/{id}")
    @PreAuthorize("hasAuthority('api_app:write')")
    @ApiOperation("删除API应用")
    public Result<Void> deleteApplication(@ApiParam("应用ID") @PathVariable String id) {
        try {
            apiApplicationService.deleteApplication(id);
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 批量更新状态
     */
    @PutMapping("/batch/status")
    @PreAuthorize("hasAuthority('api_app:write')")
    @ApiOperation("批量更新状态")
    public Result<Void> batchUpdateStatus(@RequestBody BatchUpdateStatusRequest request) {
        try {
            apiApplicationService.batchUpdateStatus(request.getIds(), request.getStatus());
            return Result.success();
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用调用统计
     */
    @GetMapping("/{id}/call-statistics")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用调用统计")
    public Result<List<Map<String, Object>>> getCallStatistics(
            @ApiParam("应用ID") @PathVariable String id,
            @ApiParam("开始日期") @RequestParam(required = false) String startDate,
            @ApiParam("结束日期") @RequestParam(required = false) String endDate) {
        try {
            List<Map<String, Object>> stats = apiApplicationService.getCallStatistics(id, startDate, endDate);
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询热门应用
     */
    @GetMapping("/popular")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询热门应用")
    public Result<List<ApiApplication>> getPopularApplications(
            @ApiParam("限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<ApiApplication> applications = apiApplicationService.getPopularApplications(limit);
            return Result.success(applications);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用统计概览
     */
    @GetMapping("/stats/overview")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用统计概览")
    public Result<Map<String, Object>> getStatsOverview() {
        try {
            Map<String, Object> stats = new HashMap<>();
            stats.put("totalCount", apiApplicationService.getTotalCount());
            stats.put("enabledCount", apiApplicationService.getEnabledCount());
            stats.put("todayNewCount", apiApplicationService.getTodayNewCount());
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用分布统计
     */
    @GetMapping("/stats/distribution")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用分布统计")
    public Result<List<Map<String, Object>>> getDistributionStats() {
        try {
            List<Map<String, Object>> stats = apiApplicationService.getDistributionStats();
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用使用趋势
     */
    @GetMapping("/stats/usage-trend")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用使用趋势")
    public Result<List<Map<String, Object>>> getUsageTrend(
            @ApiParam("天数") @RequestParam(defaultValue = "30") Integer days) {
        try {
            List<Map<String, Object>> trend = apiApplicationService.getUsageTrend(days);
            return Result.success(trend);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用错误率统计
     */
    @GetMapping("/stats/error-rate")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用错误率统计")
    public Result<List<Map<String, Object>>> getErrorRateStats() {
        try {
            List<Map<String, Object>> stats = apiApplicationService.getErrorRateStats();
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用性能统计
     */
    @GetMapping("/stats/performance")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用性能统计")
    public Result<List<Map<String, Object>>> getPerformanceStats() {
        try {
            List<Map<String, Object>> stats = apiApplicationService.getPerformanceStats();
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询最近活跃的应用
     */
    @GetMapping("/recent-active")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询最近活跃的应用")
    public Result<List<ApiApplication>> getRecentActiveApplications(
            @ApiParam("限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<ApiApplication> applications = apiApplicationService.getRecentActiveApplications(limit);
            return Result.success(applications);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询长时间未使用的应用
     */
    @GetMapping("/inactive")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询长时间未使用的应用")
    public Result<List<ApiApplication>> getInactiveApplications(
            @ApiParam("天数") @RequestParam(defaultValue = "30") Integer days) {
        try {
            List<ApiApplication> applications = apiApplicationService.getInactiveApplications(days);
            return Result.success(applications);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询高频调用应用
     */
    @GetMapping("/high-frequency")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询高频调用应用")
    public Result<List<ApiApplication>> getHighFrequencyApplications(
            @ApiParam("限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<ApiApplication> applications = apiApplicationService.getHighFrequencyApplications(limit);
            return Result.success(applications);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用IP访问统计
     */
    @GetMapping("/{id}/ip-access")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用IP访问统计")
    public Result<List<Map<String, Object>>> getIpAccessStats(@ApiParam("应用ID") @PathVariable String id) {
        try {
            List<Map<String, Object>> stats = apiApplicationService.getIpAccessStats(id);
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用API调用分布
     */
    @GetMapping("/{id}/api-call-distribution")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用API调用分布")
    public Result<List<Map<String, Object>>> getApiCallDistribution(@ApiParam("应用ID") @PathVariable String id) {
        try {
            List<Map<String, Object>> distribution = apiApplicationService.getApiCallDistribution(id);
            return Result.success(distribution);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用时段访问统计
     */
    @GetMapping("/{id}/hourly-access")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用时段访问统计")
    public Result<List<Map<String, Object>>> getHourlyAccessStats(@ApiParam("应用ID") @PathVariable String id) {
        try {
            List<Map<String, Object>> stats = apiApplicationService.getHourlyAccessStats(id);
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 查询应用月度统计
     */
    @GetMapping("/{id}/monthly")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("查询应用月度统计")
    public Result<List<Map<String, Object>>> getMonthlyStats(
            @ApiParam("应用ID") @PathVariable String id,
            @ApiParam("月数") @RequestParam(defaultValue = "6") Integer months) {
        try {
            List<Map<String, Object>> stats = apiApplicationService.getMonthlyStats(id, months);
            return Result.success(stats);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    /**
     * 检查应用名称是否可用
     */
    @GetMapping("/check-name")
    @PreAuthorize("hasAuthority('api_app:read')")
    @ApiOperation("检查应用名称是否可用")
    public Result<Boolean> checkAppNameAvailable(
            @ApiParam("应用名称") @RequestParam String appName,
            @ApiParam("排除的应用ID") @RequestParam(required = false) String excludeId) {
        try {
            boolean available = !apiApplicationService.existsByAppName(appName, excludeId);
            return Result.success(available);
        } catch (Exception e) {
            return Result.error(ResultCode.ERROR, e.getMessage());
        }
    }
    
    // ==================== 请求数据结构 ====================
    
    public static class CreateApplicationRequest {
        @NotBlank(message = "应用名称不能为空")
        private String appName;
        
        private String description;
        
        @NotBlank(message = "联系邮箱不能为空")
        private String contactEmail;
        
        private String allowedIps;
        private Integer status = 1;
        
        // getters and setters
        public String getAppName() { return appName; }
        public void setAppName(String appName) { this.appName = appName; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getContactEmail() { return contactEmail; }
        public void setContactEmail(String contactEmail) { this.contactEmail = contactEmail; }
        public String getAllowedIps() { return allowedIps; }
        public void setAllowedIps(String allowedIps) { this.allowedIps = allowedIps; }
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
    
    public static class UpdateApplicationRequest {
        @NotBlank(message = "应用名称不能为空")
        private String appName;
        
        private String description;
        
        @NotBlank(message = "联系邮箱不能为空")
        private String contactEmail;
        
        private String allowedIps;
        private Integer status;
        
        // getters and setters
        public String getAppName() { return appName; }
        public void setAppName(String appName) { this.appName = appName; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getContactEmail() { return contactEmail; }
        public void setContactEmail(String contactEmail) { this.contactEmail = contactEmail; }
        public String getAllowedIps() { return allowedIps; }
        public void setAllowedIps(String allowedIps) { this.allowedIps = allowedIps; }
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
    
    public static class BatchUpdateStatusRequest {
        @NotEmpty(message = "应用ID列表不能为空")
        private List<String> ids;
        
        private Integer status;
        
        // getters and setters
        public List<String> getIds() { return ids; }
        public void setIds(List<String> ids) { this.ids = ids; }
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
}